/*
 * glprint.c
 *
 */

#include <dogon/glprint.h>
#include <dogon/gl.h>
#include <lobi/image.h>
#include <assert.h>

static GLuint base;		// Base Display List For The Font
static GLuint fonttex_id;

static int loop;

GLvoid BuildFont(GLvoid)	// Build Our Font Display List
{
  float	cx;			// Holds Our X Character Coord
  float	cy;			// Holds Our Y Character Coord

  base=glGenLists(256);		// Creating 256 Display Lists

//	glActiveTexture(GL_TEXTURE4);
  glBindTexture(GL_TEXTURE_2D, fonttex_id);

  for (loop=0; loop<256; loop++) // Loop Through All 256 Lists
    {
      cx=((float)(loop%16))/16.0f; // X Position Of Current Character
      cy=((float)(loop/16))/16.0f; // Y Position Of Current Character

#define constant 0.0625f
      glNewList(base+loop,GL_COMPILE); // Start Building A List
      glBegin(GL_QUADS);	// Use A Quad For Each Character
      glTexCoord2f(cx,1-cy-constant); // Texture Coord (Bottom Left)
      glVertex2i(0,0);		// Vertex Coord (Bottom Left)
      
      glTexCoord2f(cx+constant,1-cy-constant); // Texture Coord (Bottom Right)
      glVertex2i(16,0);		// Vertex Coord (Bottom Right)
      
      glTexCoord2f(cx+constant,1-cy); // Texture Coord (Top Right)
      glVertex2i(16,16);	// Vertex Coord (Top Right)

      glTexCoord2f(cx,1-cy);	// Texture Coord (Top Left)
      glVertex2i(0,16);		// Vertex Coord (Top Left)
      glEnd();			// Done Building Our Quad (Character)
      glTranslated(10,0,0);	// Move To The Right Of The Character
      glEndList();		// Done Building The Display List
    } // Loop Until All 256 Are Built
}

GLvoid KillFont(GLvoid)		// Delete The Font From Memory
{
  glDeleteLists(base,256);	// Delete All 256 Display Lists
}

void gl_print(int x, int y, char *string, int set) // Where The Printing Happens
{
  if (set != 0) set = 1; /* if not 0, its italics */

  glEnable(GL_TEXTURE_2D);
  glDisable(GL_DEPTH_TEST);
  glEnable(GL_BLEND);
  glBlendFunc(GL_ONE,GL_ONE);

  glMatrixMode(GL_PROJECTION);
  glPushMatrix();
  glLoadIdentity();
  glOrtho(0,640,0,480,-1,1);
  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  glLoadIdentity();
  glTranslated(x,y,0);
  
//	glActiveTexture(GL_TEXTURE4);
  glBindTexture(GL_TEXTURE_2D, fonttex_id);
  glListBase(base-32+(128*set));
  glCallLists((GLsizei)strlen(string),GL_BYTE,string);

  glMatrixMode(GL_PROJECTION);
  glPopMatrix();
  glMatrixMode(GL_MODELVIEW);
  glPopMatrix();

  glEnable(GL_DEPTH_TEST);
  glDisable(GL_BLEND);
  glDisable(GL_TEXTURE_2D);
}

int  gl_print_done(void)
{
  KillFont();
  glDeleteTextures(1,&fonttex_id);
  return 0;
}


int gl_print_init(char* data, unsigned len, int type)
{
  int retval;
  struct image_t image;

  assert(data);

  /* read an image */
  image_init(&image);
  retval = image_sread(data,len,type,&image);
  assert(retval == 0);

  /* now we can use image */
  {
    glGenTextures(1,&fonttex_id);

//		glActiveTexture(GL_TEXTURE4);
    glBindTexture(GL_TEXTURE_2D,fonttex_id);

    assert(glGetError()==GL_NO_ERROR);

    glPixelStorei(GL_UNPACK_ALIGNMENT,1);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
    assert(glGetError()==GL_NO_ERROR);
    
    glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,image.width,image.height,0,GL_RGB,GL_UNSIGNED_BYTE,image.pixels);
    assert(glGetError()==GL_NO_ERROR);
  }
  /* free the image */
  image_free(&image);
  
  BuildFont();
  return 0;
}

